package com.ubxtech.web.handler.auth.impl;

import cn.hutool.core.util.StrUtil;
import com.ubxtech.web.annotation.AuthTypeEnum;
import com.ubxtech.web.handler.auth.AuthCollectService;
import com.ubxtech.web.handler.auth.LoginAuthService;
import com.ubxtech.web.properties.AuthProperties;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

/**
 * 利用表达式鉴权,可以实现多重组合,复合js的执行脚本即可
 * @author Victor.Xiao
 * @since 2023-09-07 15:51
*/
@Slf4j
public class ExpressAuthServiceImpl implements LoginAuthService {

    private ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");

    private AuthCollectService authCollectService;
    private AuthProperties authProperties;

    public ExpressAuthServiceImpl(AuthCollectService authCollectService,AuthProperties authProperties) {
        this.authCollectService = authCollectService;
        this.authProperties = authProperties;
    }
    /**
     * 鉴权
     * @author Victor.Xiao
     * @since 2022-01-17 11:36
     * @param request request
     * @param response response
     * @param handler handler
     * @return boolean
     */
    @Override
    public boolean auth(HttpServletRequest request, HttpServletResponse response, Object handler){
        String express = authProperties.getExpress();
        if (StrUtil.isBlank(express)) {
            return false;
        }
        if (AuthTypeEnum.none.toString().equalsIgnoreCase(express)) {
            return true;
        }
        try {
            express = express.toLowerCase();
            if (express.contains(AuthTypeEnum.none.toString())) {
                express = express.replaceAll(AuthTypeEnum.none.toString(), "true");
            }
            if (express.contains(AuthTypeEnum.cloud.toString())) {
                express = express.replaceAll(AuthTypeEnum.cloud.toString(), String.valueOf(authCollectService.cloudAuth(request, response, handler)));
            }
            if (express.contains(AuthTypeEnum.sign.toString())) {
                express = express.replaceAll(AuthTypeEnum.sign.toString(), String.valueOf(authCollectService.signAuth(request, response, handler)));
            }
            if (express.contains(AuthTypeEnum.local.toString())) {
                express = express.replaceAll(AuthTypeEnum.local.toString(), String.valueOf(authCollectService.localAuth(request, response, handler)));
            }
            Object obj = jse.eval(express);
            return "true".equalsIgnoreCase(obj.toString());
        } catch (Exception e) {
            log.error("express auth eval error " ,e);
        }
        return false;
    }

}
